package com.itheima.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.anno.Log;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpLogMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.*;
import com.itheima.service.EmpLogService;
import com.itheima.service.EmpService;
import com.itheima.util.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

@Service
public class EmpServiceImpl  implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private EmpExprMapper empExprMapper;

    @Autowired
    private EmpLogService empLogService;

    /**
     * 条件分页查询
     * @param empQueryParam
     * @return
     */
    @Override
    public PageBean page(EmpQueryParam empQueryParam) {
        //1:使用分页插件 开始介入分页操作
        PageHelper.startPage(empQueryParam.getPage(),empQueryParam.getPageSize());
        //2:执行sql语句
        List<Emp> rows = empMapper.list(empQueryParam);//条件参数 传递到mapper
        //3: 向下转型
        Page<Emp> p = (Page<Emp>) rows;
        //4:返回
        return new PageBean(p.getTotal(),p.getResult());
    }

    /**
     * 完成员工信息的添加
     * @param emp 员工基本信息+员工的工作经历
     */
    @Log
    @Override
    @Transactional(rollbackFor = Exception.class) // 开启事务控制   try...catch...
        // rollbackFor = Exception.class  表示发生异常就回滚
        //  默认只回滚 运行期异常
    public void save(Emp emp){
       try{
           //1:保存员工基本信息
           // 补全缺失的属性
           emp.setCreateTime(LocalDateTime.now());
           emp.setUpdateTime(LocalDateTime.now());
           System.out.println("存储之前:"+emp);

           //存到 emp表中
           empMapper.insert(emp);
           // 想法  如果  新增之后 将最新的id 存到 emp中就好了
           System.out.println("存储之后:"+emp);

//        System.out.println(1/0);//运行期异常  只有执行的时候遇到异常 才会在程序中体现出来
//        if(true){
//            throw new Exception();// 直接抛出一个编译期异常  在编译阶段 必须处理 否则编译不过
//                                  // 只有执行的时候遇到异常 才会在程序中体现出来
//        }

           // 2:保存员工的工作经历信息
           List<EmpExpr> exprList = emp.getExprList();
           if(exprList!=null && exprList.size()>0){//如果有工作经历且工作经历大于0条
               //再往数据库添加
               for (EmpExpr empExpr : exprList) {
                   // 员工工作经历 补充属性
                   empExpr.setEmpId(emp.getId());//员工经历必然属于某个员工
//                empExprMapper.insert(empExpr);//准备好一条 插入一条
               }
               // exprList.forEach(empExpr ->empExpr.setEmpId(emp.getId()));
               //循环做完 每个工作经历都有 所属员工  存到数据库 emp_expr表中
               //批量添加
               empExprMapper.insertBatch(exprList);
           }
       }finally {
           //不管 新增员工 是否出现异常  都要进行日志的记录
           //创建empLog对象
           EmpLog empLog = new EmpLog();
           empLog.setOperateTime(LocalDateTime.now());
           empLog.setInfo("新增员工信息:"+emp);
           empLogService.insertLog(empLog);

       }

    }

//
//    @Override
//    public PageBean page(Intege    /**
////     * 使用 分页插件 完成分页查询
////     * @param page
////     * @param pageSize
////     * @return
////     */r page, Integer pageSize) {
//        //1:使用分页插件 开始介入分页操作
//        PageHelper.startPage(page,pageSize);// page:页码  pageSize:每页显示条数
//        //2:执行sql语句  我们写了一条 分页插件会执行成两条
//        List<Emp> rows = empMapper.list();
//        // 底层的集合是Page对象
//        // List-的儿子-ArrayList-的儿子-Page
//        Page<Emp> p = (Page<Emp>) rows;//将查询结果的接口类型 向下还原成 Page
//        //p是 ArrayList子类  其实也是 分页插件中 封装结果数据的对象
//        //  总条数   当前页的数据 都会在p中  获取总条数 getTotal()  获取当前页数据  getResult()
//        return new PageBean(p.getTotal(),p.getResult());
//    }
    /*
      根据页码和每页显示条数  查询出数据 封装到 PageBean对象
     */
//    @Override
//    public PageBean page(Integer page, Integer pageSize) {
//        //1:查询总记录数
//        Long total = empMapper.count();
//        //2:获取 当前页记录--展示的数据
//        Integer start = (page - 1) * pageSize;//算出当前页查询的起始索引
//        List<Emp> rows = empMapper.list(start, pageSize);
//        //3:封装到PageBean对象中 并返回
//        return new PageBean(total,rows);
//    }




    @Override
    public List<Emp> list() {
        return empMapper.list(null);
    }
    //批量删除 员工信息
    @Override
    @Transactional
    @Log
    public void deleteByIds(List<Integer> ids) {
        //1: 批量  删除员工基本信息
        empMapper.deleteByIds(ids);

        //2:批量 删除员工工作经历
        empExprMapper.deleteByEmpIds(ids);
    }
   // 根据员工id 查询员工详情 (基本信息+工作经历列表)
    @Override
    public Emp getInfo(Integer id) {
        //1:查询基本信息
        Emp emp = empMapper.getById(id);//查询 员工表
        //2:查询工作经历
        Integer empId = emp.getId();
        List<EmpExpr> exprList = empExprMapper.getByEmpId(empId);
        //3: 将查询到工作经历设置到员工基本信息中
        emp.setExprList(exprList);
        return emp;
    }

    @Override
    @Transactional
    @Log
    public void update(Emp emp) {
        //1:根据员工id修改 员工基本信息
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.updateById(emp);//修改基本信息

        Integer empId = emp.getId();
        //2:根据员工id 删除 员工工作经历
//        ArrayList<Integer> empIds = new ArrayList<>();
//        empIds.add(emp.getId());
//        empExprMapper.deleteByEmpIds(empIds);
        empExprMapper.deleteByEmpIds(Arrays.asList(empId));
        //3:重新添加员工工作经历
        List<EmpExpr> exprList = emp.getExprList();
        if(exprList!=null && exprList.size()>0){//如果有工作经历且工作经历大于0条
            //再往数据库添加
            for (EmpExpr empExpr : exprList) {
                // 员工工作经历 补充属性
                empExpr.setEmpId(emp.getId());//员工经历必然属于某个员工
            }
            empExprMapper.insertBatch(exprList);
        }

    }

    /**
     *   登录
     * @param emp   封装的用户名和密码
     * @return
     */
    @Override
    public LoginInfo login(Emp emp) {
        // empLogin 根据用户名和密码 去数据库查询出来的用户对象
        Emp empLogin = empMapper.getUsernameAndPassword(emp);
        // 如果 empLogin 不为空  说明用户名密码正确
        if(empLogin!=null){
            //生成jwt令牌
            Map<String,Object> claims = new HashMap<>();
            claims.put("id",empLogin.getId());//存id
            claims.put("username",empLogin.getUsername());//用户名
            String token = JwtUtils.generateJwt(claims);

            //封装 LoginInfo对象
            LoginInfo loginInfo = new LoginInfo(empLogin.getId(),empLogin.getUsername(),empLogin.getName(),token);
            return loginInfo;
        }
        //如果 empLogin为null 说明 用户名密码错误
        return null;
    }
}
